#!/bin/bash

# @LICENSE(NICTA_CORE)

# Echo all commands if V=3; maximum verbosity.
if [ 0${V} -ge 3 ]; then
    set -x
fi

# Check usage.
if [ $# -lt 3 ]; then
    echo "Usage: $0 <kernel elf> <user elf> <output file> [<other files for DITE>]"
    exit 1
fi
KERNEL_IMAGE=$1
USER_IMAGE=$2
OUTPUT_FILE=$3

if [ "$PLAT" == "pxa255" ]; then
    ENTRY_ADDR=0xa2000000
    DITE_ADDR=0xa0300000
    FORMAT=elf32-littlearm
elif [ "$PLAT" == "realview" ]; then
    ENTRY_ADDR=0x72000000
    DITE_ADDR=0x70300000
    FORMAT=elf32-littlearm
elif [ "$PLAT" == "nslu2" ]; then
    ENTRY_ADDR=0x00100000;
    DITE_ADDR=0x00400000;
    FORMAT=elf32-bigarm
else
    ENTRY_ADDR=0x82000000
    DITE_ADDR=0x80300000
    FORMAT=elf32-littlearm
fi

shift 3

# Ensure files exist.
if [ ! -e ${KERNEL_IMAGE} ]; then
    echo "File '${KERNEL_IMAGE}' does not exist."; exit 1
else
    # Only echo what kernel image we're using if verbosity is turned on. 0 is
    # prepended to ${V} because V may not be set.
    if [ 0${V} -ge 2 ]; then
        echo "Using ${KERNEL_IMAGE} as kernel image";
    fi
fi

if [ ! -e ${USER_IMAGE} ]; then
    echo "File '${USER_IMAGE}' does not exist."; exit 1
else
    # Only echo what kernel image we're using if verbosity is turned on. 0 is
    # prepended to ${V} because V may not be set.
    if [ 0${V} -ge 2 ]; then
        echo "Using ${USER_IMAGE} as rootserver image";
    fi
fi

# Get the script's location.
if [ "`uname`" == "Darwin" ]; then
    # MacOS doesn't have GNU readlink.
    SCRIPT_PATH=$([[ ${BASH_SOURCE[0]} = /* ]] && echo "${BASH_SOURCE[0]}" || echo "${PWD}/${BASH_SOURCE[0]}")
else
    SCRIPT_PATH=$(readlink -f ${BASH_SOURCE[0]})
fi
SCRIPT_DIR="$(dirname "${SCRIPT_PATH}")"

# Create working directory.
# Warning: mktemp functions differently on Linux and OSX.
TMPDIR=`mktemp -d -t seL4XXXX`
fail() {
    echo "(failed)" > /dev/stderr
    rm -rf ${TMPDIR}
    exit 1
}

# Assume that whoever has invoked this script (typically a parent Makefile) has
# set V appropriately to indicate the level of verbosity of messages desired.
if [ 0${V} -gt 0 ]; then
    verbosity=-v
    for i in $@; do echo "Additional ELF $i"; done
else
    verbosity=
fi

#
# Convert user ELF into a dite image.
#
# The last bit of magic adds "-R" to the beginning of every item in a list of
# filenames.
#
dite --elf-modify-physaddr ${DITE_ADDR}\
        -D 0 ${USER_IMAGE} \
        -o "${TMPDIR}/user.dite" \
        ${verbosity} \
        `for i in $@; do echo -n '' -R $i; done` || fail

#
# Convert userspace / kernel into object files containing blobs of data.
#
${TOOLPREFIX}ld -T "${SCRIPT_DIR}/kernel.bin.lds" \
        --oformat ${FORMAT} -r -b binary ${KERNEL_IMAGE} \
        -o "${TMPDIR}/kernel.o" || fail
${TOOLPREFIX}ld -T "${SCRIPT_DIR}/user.bin.lds" \
        --oformat ${FORMAT} -r -b binary "${TMPDIR}/user.dite" \
        -o "${TMPDIR}/user.o" || fail

#
# Link everything together to produce the final ELF image.
#
${TOOLPREFIX}ld -T "${SCRIPT_DIR}/linker.lds" \
        --oformat ${FORMAT} \
        "${SCRIPT_DIR}/elfloader.o" "${TMPDIR}/kernel.o" "${TMPDIR}/user.o" \
        -Ttext=${ENTRY_ADDR} -o "${OUTPUT_FILE}" \
        || fail


# Done
rm -rf ${TMPDIR}
exit 0
